package com.object.bases;


/*
## 抽象类
    如果一个class定义了方法，但没有具体执行代码，这个方法就是抽象方法，抽象方法用abstract修饰。
    因为无法执行抽象方法，因此这个类也必须申明为抽象类（abstract class）。
    使用abstract修饰的类就是抽象类。我们无法实例化一个抽象类：
    抽象类本身被设计成只能用于被继承，因此，抽象类可以强迫子类实现其定义的抽象方法，否则编译会报错。因此，抽象方法实际上相当于定义了“规范”。
## 面向抽象编程
    当我们定义了抽象类Person，以及具体的Student、Teacher子类的时候，我们可以通过抽象类Person类型去引用具体的子类的实例：
    这种引用抽象类的好处在于，我们对其进行方法调用，并不关心Person类型变量的具体子类型：
    同样的代码，如果引用的是一个新的子类，我们仍然不关心具体类型：
    这种尽量引用高层类型，避免引用实际子类型的方式，称之为面向抽象编程。
    面向抽象编程的本质就是：
    上层代码只定义规范（例如：abstract class Person）；
    不需要子类就可以实现业务逻辑（正常编译）；
    具体的业务逻辑由不同的子类实现，调用者并不关心。
## 小结
    通过abstract定义的方法是抽象方法，它只有定义，没有实现。抽象方法定义了子类必须实现的接口规范；
    定义了抽象方法的class必须被定义为抽象类，从抽象类继承的子类必须实现抽象方法；
    如果不实现抽象方法，则该子类仍是一个抽象类；
    面向抽象编程使得调用者只关心抽象方法的定义，不关心子类的具体实现。
 */
public class AbstractClassStu {
    public static void main(String[] args) {
        Personn p = new Studentn();
        p.run();
    }
}
abstract class Personn {
    public abstract void run();
}

class Studentn extends Personn {
    @Override
    public void run() {
        System.out.println("Student.run");
    }
}